home *** CD-ROM | disk | FTP | other *** search
/ Delphi 2.0 - Programmer's Utilities Power Pack / Delphi 2.0 Programmer's Utilities Power Pack.iso / m_to_r / reporter / reports.int < prev    next >
Encoding:
Text File  |  1996-09-15  |  23.2 KB  |  479 lines

  1. unit Reports;
  2.  
  3. interface
  4. Uses SysUtils, Classes,
  5.      ExtCtrls, Chart2FX, Graphics, DB,
  6.      Printers, WinTypes;
  7.  
  8. Const
  9.      { Note:  the first seven styles are exclusive to each other.  If more
  10.               than one of these styles is indicated, the first (lowest
  11.               constant) will be chosen }
  12.      ttaLeft          = $0000;
  13.      ttaRight         = $0001;
  14.      ttaCenter        = $0002;
  15.      ttaLeftMargin    = $0004;
  16.      ttaRightMargin   = $0008;
  17.      ttaBandHCenter   = $0010;
  18.      ttaBandVCenter   = $0020;
  19.      ttaTopOfBand     = $0040;
  20.      ttaBottomOfBand  = $0080;
  21.  
  22.      { btXXXX - these styles can be combined to produce a border with
  23.                 any combination of lines.  For example, btTop + btBottom
  24.                 produces a box with only the top and bottom line visible }
  25.      btNone   = $0000;
  26.      btBox    = $0001;
  27.      btTop    = $0002;
  28.      btBottom = $0004;
  29.      btRight  = $0008;
  30.      btLeft   = $0010;
  31.  
  32. Type
  33.     { forwards }
  34.     tFixedReportBand = Class;
  35.     tRecurringReportBand = Class;
  36.  
  37.     { enumerated types }
  38.     tReportStatus  = ( rsIdle, rsRunning, rsAborted );
  39.     tBandStatus    = ( bsContinue, bsDone, bsAbort );
  40.     tShadowStyles  = ( stNone, stTopLeft, stTopRight,
  41.                        stBottomLeft, stBottomRight );
  42.  
  43.     { Exceptions }
  44.  
  45.     { eReportError is a general sort of exception that gets raised
  46.       whenever you attempt to do something the reporter can't do, like
  47.       calling an output function before the report has begun. }
  48.     eReportError  = Class ( Exception );
  49.  
  50.     { eBandOutOfBounds is called when you attempt to print outside the
  51.       margins of the current band.  The actual type of the exception
  52.       (eBandOverFlow or eBandUnderFlow) as well as the accompanying
  53.       message lets you know in which the direction you went out of bands.
  54.       This applies to text output only. }
  55.     eBandOutOfBounds = Class ( Exception );
  56.     eBandOverflow = Class ( eBandOutOfBounds );
  57.     eBandUnderflow = Class ( eBandOutOfBounds );
  58.  
  59.  
  60.     { events }
  61.  
  62.     { These events are explained in detail in the declaration of the
  63.       Reporter class below }
  64.     tReportInit   = Procedure of Object;
  65.     tReportDone   = Procedure of Object;
  66.     tBetweenPages = Procedure of Object;
  67.  
  68.     tBandInit     = Procedure (     Band   : tRecurringReportBand ) of Object;
  69.  
  70.     tNewBand      = Procedure (     Band   : tFixedReportBand;
  71.                                 Var Status : tBandStatus ) of Object;
  72.  
  73.  
  74.     { classes }
  75.  
  76.     { You may read/write the value of a tPrinterUnit variable in one
  77.       of three units: Printer Dots, Inches or Millimeters.
  78.       Reading a value:
  79.               Value := PrinterUnit.AsInches;
  80.  
  81.       Setting a value:
  82.               PrinterUnit.AsDots := 300;
  83.        }
  84.     tPrinterUnit = Class
  85.     Public
  86.           Property AsDots   : Integer;
  87.           Property AsInches : Extended;
  88.           Property AsMils   : Extended;
  89.     End;
  90.  
  91.     { tConvertPrinterUnit gives you the ability to convert between any
  92.       of the three basic units.
  93.          To Convert Inches to Dots:
  94.             Value := ConvertUnit.Inches(2.0).AsDots;
  95.          To Convert Millimeters to Inches:
  96.             Value := ConvertUnit.Mils(20).AsInches;
  97.          To Convert Dots to Millimeters:
  98.             Value := ConvertUnit.Dots(450).AsMils; }
  99.     tConvertPrinterUnit = Class ( tPrinterUnit )
  100.     Public
  101.           Function Dots   ( Value : Integer  ) : tPrinterUnit;
  102.           Function Inches ( Value : Extended ) : tPrinterUnit;
  103.           Function Mils   ( Value : Extended ) : tPrinterUnit;
  104.     End;
  105.  
  106.  
  107.  
  108.     { I've chosen to implement printing in "BANDS" to facilitate database
  109.       reporting.  Each band knows about its own dimensions and can handle
  110.       overflow, etc. without help from the parent reporter.  The band needs
  111.       the reporter for access to the canvas.
  112.  
  113.       tFixedReportBand is the basic band object.  It provides all report
  114.       output functions (aside from those provided directly through access
  115.       to the reporter's canvas).  All band output functions are relative
  116.       to the currently printing band.  See the declarations for a
  117.       description of each output call's purpose and parameters }
  118.  
  119.     tFixedReportBand = Class ( tObject )
  120.     Public
  121.           { NextLine advance the print head one "line" based on the height
  122.             of the current font.  PreviousLine moves backward one line. }
  123.           Procedure   NextLine;
  124.           Procedure   PreviousLine;
  125.  
  126.           { TopofBand positions the print head so that the next text output
  127.             call (unless otherwise specified in alignment) will print at the
  128.             top of the band.  The other ...OfBand functions behave similarly.
  129.             These functions will not be needed often due to the inclusion of
  130.             ttaLeftMargin, ttaRightMargin, ttaTopOfBand, and ttaBottomOfBand
  131.             styles in the alignment argument of output calls }
  132.           Procedure   TopOfBand;
  133.           Procedure   LeftOfBand;
  134.           Procedure   RightOfBand;
  135.           Procedure   BottomOfBand;
  136.  
  137.           { TabTo positions the print head (horizontally) across the page
  138.             with respect to the left margin.  Position is specified in
  139.             printer dots.  Use Reporter.ConvertWidth if you want to specify
  140.             a tab in units other than dots.  RelativeTabTo positions the
  141.             print head with respect to the current position and can be either
  142.             positive or negative }
  143.           Procedure   TabTo ( Position : Extended );
  144.           Procedure   RelativeTabTo ( Amount : Extended );
  145.           { MoveY and AdjustY behave just like TabTo and RelativeTabTo, except
  146.             they move the print head vertically across the band. }
  147.           Procedure   MoveY ( Position : Extended );
  148.           Procedure   AdjustY ( Amount : Extended );
  149.  
  150.           { TextOut prints the string specified by Item subject to the
  151.             aligment specified by Alignment.  MastRpt provides several
  152.             good examples of the use of Alignment in positioning output }
  153.           Procedure   TextOut ( Item      : String;
  154.                                 Alignment : Word );
  155.  
  156.           { BoxTextOut adds the capability of printing lines (with
  157.             optional shadow) around text.  BoxStyle (see BoxStyle constants
  158.             above) allows you to place lines around text.  BoxOffset specifes
  159.             how far away from the text the box will print.  LineWidth specifies
  160.             the width of the sides of the box.  ShadowStyle specifies the
  161.             position of the shadow (or no shadow), and ShadowOffset specifies
  162.             the apparent depth of the shadow (distance from the box) }
  163.           Procedure   BoxTextOut ( Item         : String;
  164.                                    Alignment    : Word;
  165.                                    BoxStyle     : Word;
  166.                                    BoxOffset    : Word;
  167.                                    LineWidth    : Word;
  168.                                    ShadowStyle  : tShadowStyles;
  169.                                    ShadowOffset : Word );
  170.  
  171.         { DirectMemoOut prints out a pChar vairable in memo format.
  172.           The Width specifies the width of the memo when it prints.
  173.           The height of the memo will be the lesser of:
  174.                    1) the height you specify,
  175.                    2) the height of the band,
  176.                    3) the height needed to display the entire memo.
  177.           Set Height to 0 if you want the memo to use the full band height
  178.           (if it needs to).  Any memo output below this point will be
  179.           clipped.  The normal alignment constants apply.  In addition to
  180.           this, if you specify ttaLeft, ttaRight or ttaCenter, the text
  181.           within the memo box will also be aligned (left,right,center)
  182.           with respect to the memo box's borders. }
  183.           Procedure DirectMemoOut ( MemoText  : pChar;
  184.                                     Height,
  185.                                     Width     : Extended;
  186.                                     Alignment : Word );
  187.  
  188.  
  189.           { MemoOut works like DirectMemoOut above, except the Memo data is
  190.             pulled directly from a memo field (either tMemo or tDBMemo }
  191.           Procedure MemoOut ( Item      : tCustomMemo;
  192.                               Height,
  193.                               Width     : Extended;
  194.                               Alignment : Word );
  195.  
  196.  
  197.           { DBMemoOut works like DirectMemoOut above, except the Memo data
  198.             is pulled directly from a table's memo field }
  199.           Procedure DBMemoOut ( Item      : tField;
  200.                                 Height,
  201.                                 Width     : Extended;
  202.                                 Alignment : Word );
  203.  
  204.         { This routine prints out a tGraphic object.
  205.           Width and Height affect the output as follows:
  206.  
  207.              Width > 0  : Graphic output is exactly Width wide
  208.              Width = 0  : Graphic output is at current Graphic.Width
  209.  
  210.              Height > 0 : Graphic output is exactly Height tall
  211.              Height = 0 : Graphic output is at current Graphic.Height
  212.  
  213.           ScaleWidth and ScaleHeight affect the output as follows:
  214.  
  215.              ScaleWidth = 0  : Graphic output is unchanged.
  216.              ScaleWidth > 0  : Graphic width is multiplied by ScaleWidth/100
  217.  
  218.              ScaleHeight = 0 : Graphic output is unchanged.
  219.              ScaleHeight > 0 : Graphis height is multiplied by ScaleHeight/100
  220.  
  221.           If Width > 0 and ScaleWidth > 0 then ScaleWidth is overridden, and
  222.           likewise for Height and ScaleHeight.
  223.  
  224.           The placement of the graphic may take advantage of all of the
  225.           tTextAligment constants. }
  226.           Procedure PlaceGraphic ( Graphic       : tGraphic;
  227.                                    Alignment     : Word;
  228.                                    Width,
  229.                                    Height        : Extended;
  230.                                    ScaleWidth,
  231.                                    ScaleHeight   : Word );
  232.  
  233.           { PlaceDBGraphic operates the same way as PlaceGraphic, except
  234.             instead of passing a tGraphic to the procedure, you pass a
  235.             tGraphicField.  FishRpt is a good example of how to use this
  236.             procedure. }
  237.           Procedure PlaceDBGraphic ( DBGraphic     : tField;
  238.                                      Alignment     : Word;
  239.                                      Width,
  240.                                      Height        : Extended;
  241.                                      ScaleWidth,
  242.                                      ScaleHeight   : Word );
  243.  
  244.           { PlaceImage operates the same way as PlaceGraphic, except
  245.             instead of passing a tGraphic to the procedure, you pass a
  246.             tImage.  I don't have an example of the use of this function
  247.             in the provided sample reports }
  248.           Procedure PlaceImage ( Image         : tImage;
  249.                                  Alignment     : Word;
  250.                                  Width,
  251.                                  Height        : Extended;
  252.                                  ScaleWidth,
  253.                                  ScaleHeight   : Word );
  254.  
  255.           { PlaceChartFX operates the same way as PlaceGraphic, except
  256.             instead of passing a tGraphic to the procedure, you pass a
  257.             tChartFX object.  The additional option of ColorPrint
  258.             specifies whether or not to attempt to print the chart in
  259.             color (True for color, False for black/white).  ChrtRpt is a
  260.             good example of how to use this procedure. }
  261.           Procedure PlaceChartFX ( Chart         : tChartFX;
  262.                                    Alignment     : Word;
  263.                                    Width,
  264.                                    Height        : Extended;
  265.                                    ScaleWidth,
  266.                                    ScaleHeight   : Word;
  267.                                    ColorPrint    : Boolean );
  268.  
  269.  
  270.           { These four properties are provided for use by those wishing
  271.             to do graphics output directly to the Reporter's canvas.  The
  272.             four values bracket the current band's printable area in absolute
  273.             canvas units.  Both MastRpt and BoxRpt give examples of how to
  274.             use these properties. }
  275.           Property Left     : Word Read fLeft;
  276.           Property Right    : Word Read fRight;
  277.           Property Top      : Word Read fTop;
  278.           Property Bottom   : Word Read fBottom;
  279.     End;
  280.  
  281.  
  282.     { tRecurringReportBand adds support for a band that "fixes" it's
  283.       height to the height needed by the user to print out one
  284.       detail/group band "line".  A typical use of the SetBandBegin and
  285.       SetBandEnd procedures is demonstrated in the FishRpt example. }
  286.     tRecurringReportBand = Class ( tFixedReportBand )
  287.     Public
  288.           Procedure   SetBandBegin;
  289.           Procedure   SetBandEnd;
  290.           Procedure   ResetBand;
  291.     End;
  292.  
  293.  
  294.     tReporter = Class ( tPrinter )
  295.     Public
  296.           { This runs the report.  The functioning of the report depends
  297.             on declarations of event handlers (see below). }
  298.           Procedure Run;
  299.  
  300.           { these are functions I've inherited from tPrinter that I
  301.             don't want the user to call.  So I'm going to redeclare
  302.             them and provide stub procedures }
  303.           Procedure BeginDoc;
  304.           Procedure EndDoc;
  305.           Procedure Abort;
  306.           {+++++++++++++++++}
  307.  
  308.           { The NewPage function calls Reporter's NewPage function, which
  309.             call BetweenPages (user-defined) allowing for margin, header,
  310.             footer, and page orientation changes.  Note:  this procedure
  311.             will normally _not_ be called to create a new page.  It is
  312.             included for the case where the user is not printing
  313.             consecutively down the page, which causes a page break.
  314.             See the BoxRpt demo for an example of NewPage in use. }
  315.           Procedure NewPage;
  316.  
  317.  
  318.           { AddFullPage adds a FullPage band to the report.  This will
  319.             seldom be used, and I included it basically to give the
  320.             graphics users easy access to drawing on the full page.  This
  321.             procedure _could_ be used to place a watermark on the page. }
  322.           Procedure AddFullPage ( OnNewFullPage  : tNewband );
  323.  
  324.           { AddHeader adds a Header band to the report.  This will often
  325.             be used in reports.  See any of the reports for an example
  326.             of how to use this proceure }
  327.           Procedure AddHeader   ( OnNewHeader    : tNewBand );
  328.  
  329.           { AddDetail adds a detail band to the report.  A Detail band
  330.             consists of two parts: the initialization and the printing.
  331.             In the initialization phase (corresponding to the OnDetailInit
  332.             event), the user can tell the reporter (through the use of
  333.             SetBandBegin...SetBandEnd) how high a complete detail band is.
  334.             This allows the reporter to do two things:  1) prevent the
  335.             detail band from printing across page breaks, and 2) give the
  336.             user the ability to position output calls relative to the
  337.             current position of the band on the page.  Without a set band
  338.             height, calls to TopOfBand or BottomOfBand and output calls
  339.             that include the alignment styles ttaTopOfBand, ttaBottomOfBand,
  340.             or ttaBandVCenter will position the print head with relation
  341.             to the top and bottom margins, _not_ with respect to the current
  342.             detail band.  See FishRpt and MastRpt (especially FishRpt) for
  343.             an example of setting the band height. }
  344.           Procedure AddDetail   ( OnDetailInit   : tBandInit;
  345.                                   OnNewDetail    : tNewBand );
  346.  
  347.           { AddGroup adds a group band to the report.  A Group band surrounds
  348.             all prior AddDetail and AddGroup bands.  See SummRpt for a good
  349.             example of group bands.  Using a group band allows you to print
  350.             out detail in groups.  Usually, each group and (the only) detail
  351.             correspond to a table, linked to each other in a master-detail
  352.             relationship.  The group band's purpose then is to advance the
  353.             master table (and optionally print something) and the detail band's
  354.             purpose is to advance the detail table and print out information.
  355.             OnGroupInit allows you to set the group band's height (see AddDetail).
  356.             OnNewGroup should be used for printing out the group value, and
  357.             initializing report variables.  OnGroupSummary should be used to
  358.             advance the table and print out report variables.  Again, SummRpt
  359.             is a good example of this process.  }
  360.           Procedure AddGroup    ( OnGroupInit    : tBandInit;
  361.                                   OnNewGroup     : tNewband;
  362.                                   OnGroupSummary : tNewBand );
  363.  
  364.           { AddFooter adds a footer band to the report.  This will usually
  365.             (though not as often as a header band) be used in a report.  See
  366.             MastRpt for an example of a footer band. }
  367.           Procedure AddFooter   ( OnNewFooter    : tNewBand );
  368.  
  369.  
  370.           {Font Routines}
  371.           { SaveFont and RestoreFont work together to preserve a font across
  372.             output calls.  These will usually be used in a header or footer
  373.             to prevent changes to the detail band's font across page breaks.
  374.             See any of the reports' header or footer bands for an example
  375.             of these procedures. }
  376.           Procedure SaveFont;
  377.           Procedure RestoreFont;
  378.  
  379.           { CreateFontStyle allows you to save the current font's settings
  380.             by name, to be recalled lated by SetFontStyle.  If you want to
  381.             change a Font Style, you need to first use DeleteFontStyle to
  382.             get rid of the current font style, then CreateFontStyle to
  383.             save the new font style.  Note that if you don't call
  384.             DeleteFontStyle for any font styles you create, the reporter
  385.             will delete them for you at program termination.  See MastRpt for
  386.             an example of the use of named font styles }
  387.           Procedure CreateFontStyle ( StyleName : String );
  388.           Procedure SetFontStyle    ( StyleName : String );
  389.           Procedure DeleteFontStyle ( StyleName : String );
  390.  
  391.  
  392.           { returns the current page number }
  393.           Property PageNumber     : Word          Read fPageNumber;
  394.  
  395.           { returns a list of the currently defined font styles }
  396.           Property FontStyles     : tStringList   Read fFontStyles;
  397.  
  398.           { returns the reporter's current status.  this allows you to
  399.             know if the report terminated normally, or if the user
  400.             aborted the printing }
  401.           Property ReportStatus   : tReportStatus Read fReportStatus;
  402.  
  403.           { if you have only a detail band, and you either:
  404.                1) use a single line in the same font, or
  405.                2) have set the band's height
  406.             then using the TotalPages property with the total number of
  407.             items to be printed in the report will return the number of
  408.             pages needed to print the report.  I do not expect this
  409.             property to be used much, since the complexity of the report
  410.             doesn't really allow (easily) for this kind of calculation }
  411.           Property TotalPages[TotalItems:Word] : Word Read GetTotalPages;
  412.  
  413.           { Use the Orientation property to change the page orientation of
  414.             the report.  This property may be used before the report is run,
  415.             or from inside a BetweenPages handler (set through the OnBetweenPages
  416.             property).  BoxRpt provides an example of the use of this property
  417.             in the BetweenPages handler. }
  418.           Property Orientation    : tPrinterOrientation Read GetOrientation Write SetOrientation;
  419.  
  420.           { These properties set the margins of the page.  These properties
  421.             are of type tPrinterUnit, which means that you can read/write
  422.             them using AsDots, AsInches or AsMils, whichever suits your
  423.             fancy.  The margins restrict the printable area available to
  424.             the header, footer, and detail/group bands.  They also affect
  425.             output calls which include an Alignment specifier.  By default,
  426.             these are set to 1 inch apiece. }
  427.           Property TopMargin      : tPrinterUnit  Read fTopMargin;
  428.           Property BottomMargin   : tPrinterUnit  Read fBottomMargin;
  429.           Property LeftMargin     : tPrinterUnit  Read fLeftMargin;
  430.           Property RightMargin    : tPrinterUnit  Read fRightMargin;
  431.  
  432.           { There are some special cases (most notably memos) where the
  433.             size of a band is not known before the band prints.  However,
  434.             you often still want to prevent the band from being split
  435.             across pages.  The StretchBand property is for these occasions.
  436.             When you set StretchBand to TRUE, the Reporter calls your band
  437.             Init procedure each time it prints a band.  This allows it to
  438.             figure out how tall a band is and prevent page breaks in the
  439.             middle.  For an example of this, see the FishRpt demo. }
  440.           Property StretchBand : Boolean Read fStretchBand Write fStretchBand;
  441.  
  442.           { The PreferredUnit property is provided to let you set the
  443.             'normal' units for the report.  After setting PreferredUnit,
  444.             all positioning/output calls that take X, Y, Width, or Height
  445.             arguments will be in terms of the unit you set.  Example:
  446.                Reporter.PreferredUnit := puInches;
  447.                Band.TabTo ( 2.0 );
  448.             The above statement causes the print head to move two inches
  449.             from the left margin. }
  450.           Property PreferredUnit : tPreferredUnit Read fPreferredUnit Write fPreferredUnit;
  451.  
  452.           { ConvertWidth and ConvertHeight are provided to give you
  453.             an easy way to convert between units.  For example, to
  454.             convert millimeters (width) to dots on the printer:
  455.                     ConvertWidth.Mils(20).AsDots
  456.             This is mostly useful in the Place..., TabTo, RelativeTabTo,
  457.             MoveY, and AdjustY procedures. }
  458.           Property ConvertWidth   : tConvertPrinterUnit Read fConvertWidth;
  459.           Property ConvertHeight  : tConvertPrinterUnit Read fConvertHeight;
  460.  
  461.           { These properties let you specify procedures to run when the
  462.             report is starting, is between pages, and is done respectively.
  463.             OnReportInit is best used to set the margins, open tables, and
  464.             create font styles.  OnBetweenPages is best used if you need to swap
  465.             out header/footer bands or change the page orientation in the
  466.             middle of the report (see BoxRpt).  OnReportDone is best used
  467.             to close any datasets opened for the report. }
  468.           Property OnReportInit   : tReportInit   Write fOnReportInit;
  469.           Property OnBetweenPages : tBetweenPages Write fOnBetweenPages;
  470.           Property OnReportDone   : tReportDone   Write fOnReportDone;
  471.     End;
  472.  
  473. Var
  474.    { The Reporter itself.  Note that there is only one per program }
  475.    Reporter : tReporter;
  476.  
  477. implementation
  478. end.
  479.